import math

MC_BAND = [12890594.86, 8362377.87, 5591021, 3481989.83, 1678043.12, 0]
MC2LL = [
    [
        1.410526172116255e-8, 8.98305509648872e-6, -1.9939833816331,
        2.009824383106796e2, -1.872403703815547e2, 91.6087516669843,
        -23.38765649603339, 2.57121317296198, -0.03801003308653, 1.73379812e7,
    ],
    [
        -7.435856389565537e-9, 8.983055097726239e-6, -0.78625201886289,
        96.32687599759846, -1.85204757529826, -59.36935905485877,
        47.40033549296737,
        -16.50741931063887, 2.28786674699375, 1.026014486e7,
    ],
    [
        -3.030883460898826e-8, 8.98305509983578e-6, 0.30071316287616,
        59.74293618442277, 7.357984074871, -25.38371002664745,
        13.45380521110908,
        -3.29883767235584, 0.32710905363475, 6.85681737e6,
    ],
    [
        -1.981981304930552e-8, 8.983055099779535e-6, 0.03278182852591,
        40.31678527705744, 0.65659298677277, -4.44255534477492,
        0.85341911805263,
        0.12923347998204, -0.04625736007561, 4.48277706e6,
    ],
    [
        3.09191371068437e-9, 8.983055096812155e-6, 0.00006995724062,
        23.10934304144901, -0.00023663490511, -0.6321817810242,
        -0.00663494467273,
        0.03430082397953, -0.00466043876332, 2.5551644e6,
    ],
    [
        2.890871144776878e-9, 8.983055095805407e-6, -0.00000003068298,
        7.47137025468032, -0.00000353937994, -0.02145144861037,
        -0.00001234426596,
        0.00010322952773, -0.00000323890364, 8.260885e5,
    ],
]


# 定义BD09Projection类
class BD09Projection(object):
    def __init__(self):
        self.isWgs84 = False

    # 定义convertor方法
    def convertor(self, fromPoint, factor):
        if not fromPoint or not factor:
            return {"lng": 0, "lat": 0}
        x = factor[0] + factor[1] * abs(fromPoint["lng"])
        temp = abs(fromPoint["lat"]) / factor[9]
        y = (
            factor[2]
            + factor[3] * temp
            + factor[4] * temp * temp
            + factor[5] * temp * temp * temp
            + factor[6] * temp * temp * temp * temp
            + factor[7] * temp * temp * temp * temp * temp
            + factor[8] * temp * temp * temp * temp * temp * temp
        )
        x *= -1 if fromPoint["lng"] < 0 else 1
        y *= -1 if fromPoint["lat"] < 0 else 1
        return {"lng": x, "lat": y}

    # 定义convertMC2LL方法
    def convertMC2LL(self, point):
        if not point:
            return {"lng": 0, "lat": 0}
        lnglat = {}
        if self.isWgs84:
            lnglat["lng"] = (point["lng"] / 20037508.34) * 180
            mmy = (point["lat"] / 20037508.34) * 180
            lnglat["lat"] = (
                (180 / math.pi) *
                (2 * math.atan(math.exp((mmy * math.pi) / 180)) - math.pi / 2)
            )
            return {
                "lng": round(lnglat["lng"], 6),
                "lat": round(lnglat["lat"], 6),
            }

        temp = {"lng": abs(point["lng"]), "lat": abs(point["lat"])}

        factor = next(
            (MC2LL[i]
             for i in range(len(MC_BAND)) if temp["lat"] >= MC_BAND[i]),
            None,
        )
        lnglat = self.convertor(point, factor)
        return {
            "lng": round(lnglat["lng"], 6),
            "lat": round(lnglat["lat"], 6),
        }

    # 定义pointToLngLat方法
    def pointToLngLat(self, lng, lat):
        mercator = {"lng": lng, "lat": lat}
        return self.convertMC2LL(mercator)


if __name__ == '__main__':
    print(BD09Projection().pointToLngLat(12947467, 4836440))
    print(BD09Projection().pointToLngLat(12948342, 4836690))

    print(BD09Projection().pointToLngLat(12947474, 4836432))
